package com.itjeffrey.autocode.config;

import com.itjeffrey.autocode.filter.JwtAuthenticationTokenFilter;
import com.itjeffrey.autocode.security.SecureAccessDeniedHandler;
import com.itjeffrey.autocode.security.SecurityAuthenticationEntryPoint;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.annotation.Resource;

/**
 * Security安全相关配置
 *
 * @From: Jeffrey
 * @Date: 2020/11/30
 */
@Configuration
@EnableWebSecurity //启用SpringSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true) //启用prePost注解支持，
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Resource
    private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;
    @Resource
    private SecurityAuthenticationEntryPoint securityAuthenticationEntryPoint;
    @Resource
    private SecureAccessDeniedHandler secureAccessDeniedHandler;
    @Resource
    private SecurityProperties securityProperties;
    @Resource
    private Swagger2Properties swagger2Properties;
//    @Resource
//    private SecurityPermissionSupport securityPermissionSupport;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //基于JWT，不需要csrf
        http.cors().and().csrf().disable()
                //基于token,不需要session
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and().httpBasic().authenticationEntryPoint(securityAuthenticationEntryPoint)
                .and().authorizeRequests()
                .antMatchers(securityProperties.getOpenInterfaces()).permitAll()
                //Swagger2放行路径，不然无法访问swagger2页面（空白页），报错401
                .antMatchers(swagger2Properties.getAuthPaths()).permitAll()
                //.antMatchers("/mock/interface/**").hasAnyRole(SysConstant.ROLE_TYPE_ADMIN)
                // 跨域预检请求
                .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                //前面没有匹配上的请求，全部需要认证；
                .anyRequest().authenticated()
                .and().exceptionHandling()
                .accessDeniedHandler(secureAccessDeniedHandler);
        // 访问控制时登录状态检查过滤器
        http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
        // 启用登出配置，退出登录处理器（说明：指定配置的url不被filter拦截）
        //http.logout().logoutUrl("/user/logout").logoutSuccessUrl("/user/logout").logoutSuccessHandler
        // (customerLogoutSuccessHandler);
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        //web.ignoring是直接绕开spring security的所有filter，直接跳过验证
        //swagger2放行路径，不然访问swagger2页面时报错Failed to load API definition.
        web.ignoring().mvcMatchers(swagger2Properties.getAuthPaths());
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManager() throws Exception {
        return super.authenticationManager();
    }

//    @Bean
//    public DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler(){
//        DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler =
//                new DefaultWebSecurityExpressionHandler();
//        defaultWebSecurityExpressionHandler.setPermissionEvaluator(securityPermissionSupport);
//        return defaultWebSecurityExpressionHandler;
//    }
}
